package DuobleLink

import (
	"fmt"
	"strings"
)

//双链表的基本结构
type DuobleLinkList struct {
	head   *DuobleLinkNode
	length int
}

// 新建一个双链表
func NewDoubleLinkList() *DuobleLinkList {
	head := NewDoubleLinkNode(nil)
	return &DuobleLinkList{head, 0}
}

// 链表长度
func (dlist *DuobleLinkList) GetLength() int {
	return dlist.length
}

// 返回第一个节点
func (dlist *DuobleLinkList) GetFirstNode() *DuobleLinkNode {
	return dlist.head.next
}

// 头部节点插入
func (dlist *DuobleLinkList) InsertHead(node *DuobleLinkNode) bool {

	pHead := dlist.head

	if pHead.next == nil {

		pHead.next = node
		node.prev = pHead
		node.next = nil

		dlist.length++

		return true
	} else {
		pHead.next.prev = node
		node.next = pHead.next

		pHead.next = node
		node.prev = pHead
		dlist.length++

		return true
	}

	return false
}

func (dlist *DuobleLinkList) InsertBack(node *DuobleLinkNode) bool {
	pHead := dlist.head

	if pHead.next == nil {

		pHead.next = node
		node.prev = pHead
		node.next = nil

		dlist.length++

		return true
	} else {

		for pHead.next != nil {
			pHead = pHead.next
		}

		pHead.next = node
		node.prev = pHead

		dlist.length++

		return true
	}

	return false
}

// 返回链表
func (dlist *DuobleLinkList) String() string {
	var listString1 string
	var listString2 string

	pHead := dlist.head
	for pHead.next != nil {
		listString1 += fmt.Sprintf("--->%v", pHead.next.value)
		pHead = pHead.next
	}
	listString1 += fmt.Sprintf("-->nil")
	listString1 += "\n"

	for pHead != dlist.head {
		listString2 += fmt.Sprintf("<---%v", pHead.value)
		pHead = pHead.prev
	}

	return listString1 + "" + listString2 + "\n"
}

// 在节点dest后面插入
func (dlist *DuobleLinkList) InsertValueBack(dest *DuobleLinkNode, node *DuobleLinkNode) bool {
	pHand := dlist.head

	for pHand.next != nil && pHand.next != dest {
		pHand = pHand.next
	}

	if pHand.next == dest {

		if pHand.next.next != nil {
			pHand.next.next.prev = node
		}
		node.next = pHand.next.next
		pHand.next.next = node
		node.prev = pHand.next

		dlist.length++

		return true
	} else {
		return false
	}
}

// 在节点之前插入
func (dlist *DuobleLinkList) InsertValueHead(dest *DuobleLinkNode, node *DuobleLinkNode) bool {
	pHand := dlist.head

	for pHand.next != nil && pHand.next != dest {
		pHand = pHand.next
	}

	if pHand.next == dest {

		if pHand.next != nil {
			pHand.next.prev = node
		}
		node.next = pHand.next
		node.prev = pHand
		pHand.next = node

		dlist.length++
		return true
	} else {
		return false
	}
}

func (dlist *DuobleLinkList) InsertValueHeadByValue(dest interface{}, node *DuobleLinkNode) bool {
	pHand := dlist.head

	for pHand.next != nil && pHand.next.value != dest {
		pHand = pHand.next
	}

	if pHand.next == dest {

		if pHand.next != nil {
			pHand.next.prev = node
		}
		node.next = pHand.next
		pHand.next = node
		pHand.next = node

		dlist.length++
		return true
	} else {
		return false
	}
}

// 节点值之后
func (dlist *DuobleLinkList) InsertValueBackByValue(dest interface{}, node *DuobleLinkNode) bool {
	pHand := dlist.head

	for pHand.next != nil && pHand.next.value != dest {
		pHand = pHand.next
	}

	if pHand.next == dest {

		if pHand.next.next != nil {
			pHand.next.next.prev = node
		}
		node.next = pHand.next.next
		pHand.next.next = node
		node.prev = pHand.next

		dlist.length++

		return true
	} else {
		return false
	}
}

//返回第几个节点
func (dlist *DuobleLinkList) GetNodeAtindex(index int) *DuobleLinkNode {

	if index > dlist.length || index < -1 {
		return nil
	}

	pHead := dlist.head
	for index > -1 {

		pHead = pHead.next

		index--
	}

	return pHead

}

// 删除节点
func (dlist *DuobleLinkList) DeleteNode(node *DuobleLinkNode) bool {

	if node == nil {
		return false
	} else {
		pHead := dlist.head
		for pHead.next != nil && pHead.next != node {
			pHead = pHead.next
		}

		if pHead.next == node {

			if pHead.next.next != nil {
				pHead.next.next.prev = pHead // 设置prev
			}

			pHead.next = pHead.next.next //设置下个节点

			dlist.length--
			return true
		} else {
			return false
		}

	}

}

// 删除第几节点
func (dlist *DuobleLinkList) DeleteNodeAtindex(index int) bool {
	if index > dlist.length || index < 0 {
		return false
	}

	pHead := dlist.head

	for index > 0 {
		pHead = pHead.next
		index--
	}

	if pHead.next.next != nil {
		pHead.next.next.prev = pHead // 设置prev
	}

	pHead.next = pHead.next.next //设置下个节点

	dlist.length--

	return true
}

func (dlist *DuobleLinkList) FindString(data string) {

	pHead := dlist.head.next //第一个节点为节点 	pHead := dlist.head 使用有问题

	for pHead.next != nil {

		if strings.Contains(pHead.value.(string), data) {
			fmt.Println(pHead.value.(string))
		}

		pHead = pHead.next
	}

}
